; DISCIOP.Z80
;
;	You can use this to implement an iop recorder that will
;	record all console output to disc.
;	You can take one of the sample iop's that are available
;	and with just a little butchering end up with a console
;	recorder iop.
;	** Be sure to set the high order
;	bit in the iop's id byte.** 
;	The 5 equates at the beginning of the code block should
;	be modified as required to be compatible with the code
;	you are already using.
;	i.e. aiobyte should be changed, along with any references
;	made to it, to whatever your program calls the address
;	of iobyte.
;	bel, bdos, eof, and iops should already be defined in
;	your code. If not, fix this code to be compatible.
;
;	This module attempts to first delete, and then create a
;	file named RECORDER.  When recording is turned on, the
;	recorder file will be opened on the current default disc
;	at creation time.
;
;	Once recording is on, selecting con device 3 allows
;	recording.  After that, as long as con device 3 is
;	selected, all console output will be sent to disc.
;
;	Selecting a con device other than 3 will stop output
;	into the RECORDER file.
;
;	Using record to set recording off will the close the
;	file.
;
;	Now for the bad news.......
;	there is little (and i mean none) error checking in
;	this code.  I suggest that you add in some.
;
;	This code segment, which includes, an fcb, a 147 byte
;	dos parameter save area, a 128 byte disc buffer, and
;	a whopping 20 byte stack occupies 659 bytes. I admit
;	that this is rather tubby.  Feel free to shrink this
;	further.
;
;	THIS IS NOT MEANT TO BE A COMPLETE PACKAGE!
;	IT IS MEANT TO SERVE AS AN EXAMPLE. I HAVE YET TO SEE
;	ON ANY OF THE Z-NODES ANY EXAMPLES OF RECORDING
;	TECHNIQUES. LET ALONE ANY GOOD DOCUMENTATION ON HOW
;	TO IMPLEMENT IT. (not that this represents good
;	documentation)
;
;	It shouldnt be too much of a problem to fit this into
;	your iop, at least you get a shot of seeing how its
;	done. 
;
;	This file was assembled with zas 2.4
;
;	You can message me on the 24th street exchange
;	in sacramento calif 916 451 7179
;	by the way my name is
;      jeff herr
;
VERSION EQU 00		;DATE OF REV 08/30/86		TIME OF REV 10:37:23P  
;........................disc support............................
	ext	print	;should be somewhere in your iop code too.
;
bel	equ	7
bdos	equ	5
eof	equ	1ah
iops	equ	12
aiobyte	equ	3		;location of iobyte
;
copen
	ld	hl,(0006)	;location of dos entry
	ld	de,5		;offset into dos buffers
	add	hl,de
	ld	(dosadd),hl
	ld	hl,initarea
	ld	b,endinit-initarea
	ld	a,(iopflg)
	or	a
	jr	z,ccopen
	call	print
	db	bel,' [ALREADY ON]  ',0
	ret
ccopen
	ld	(hl),a
	inc	hl
	djnz	ccopen


	ld	c,25		;get current disc
	call	bdos		;will use until next open
	inc	a		;make it compatable
	ld	(iopfcb),a	;and place in drivecode byte of fcb
	ld	de,iopfcb
	ld	c,19		;see if u can delete it
	call	bdos
	ld	de,iopfcb
	ld	c,22		;create
	call	bdos
	CP	0ffh
	jr	nz,openok
	call	print
	db	bel,'create failure',0
	ret
openok
	ld	e,0ffh
	ld	c,32		;<---get user
	call	bdos
	ld	(ouruser),a
	ld	hl,iopflg
	ld	(hl),0ffh	;file is marked open
	inc	hl		;bump ptr
	LD	(HL),128	;set to empty buffer
	ld	hl,iopbuf
	ld	(iopptr),hl
	ret
;
cclose
	ld	a,(iopflg)
	or	a
	jr	nz,ccclose
	call	print
	db	bel,' [ALREADY OFF]  ',0
	ret

ccclose
	ld	a,eof
	ld	(closeflg),a
	call	bytewrite
	ld	a,(closeflg)
	or	a
	jr	nz,ccclose
	ld	(iopflg),a
	ret
;
conrecord
	ld	a,(aiobyte)
	and	3		;mask all but con: bits
	cp	3		;check if device 3
	ret	nz		;if dev not = 3 quit
	ld	a,(iopflg)	;if record file already open..
	or	a		;..open=not zero..
	ret	z		;..then quit

	ld	(ostack),sp	;now were gonna do it
	ld	sp,stack	;well use about 10 stack entries
	push	af
	push	bc
	push	de
	push	hl
	ld	a,c
	call	bytewrite
	pop	hl
	pop	de
	pop	bc
	pop	af
	ld	sp,(ostack)
	ret
;
bytewrite
	ld	hl,(iopptr)	;get the pointer
	ld	(hl),a		;stash data byte
	inc	hl		;bump to next output byte
	ld	(iopptr),hl	;stash it
	ld	a,(iopcnt)	;get adrs of count
	dec 	a
	ld	(iopcnt),a	;bump it
	ret	nz

;here is the write operation. simple block write.

	ld	a,128
	ld	(iopcnt),a	;set for next time
	ld	hl,iopbuf	;
	ld	(iopptr),hl	;set pointer for next time

	ld	hl,(dosadd)	;get pointer to dos
	ld	de,savbuf	;get pointer to save loc
	ld	bc,147		;set cnt
	ldir			;save dos buffers for reentrant ops

	ld	c,47		;<---return dma adrs
	call	bdos		
	ld	(dosptr),hl	;stash 

	ld	de,iopbuf
	ld	c,26		;<---set dma adrs for our ops
	call	bdos

	ld	a,(ouruser)
	ld	e,a
	ld	c,32		;<---set user for our ops
	call	bdos

	ld	de,iopfcb
	ld	c,21		;<---write
	call	bdos

	ld	a,(closeflg)
	or	a
	jr	z,noclose

	xor	a
	ld	(closeflg),a
	ld	de,iopfcb
	ld	c,16		;<---close the file if cclose set the flag
	call	bdos
	
noclose
	ld	de,(dosptr)
	ld	c,26		;<---restore the old dma adrs
	call	bdos

	ld	de,(dosadd)
	ld	hl,savbuf
	ld	bc,147
	ldir

	ret
;
iopflg	db	0		;Output file opened flag (z=no)
iopcnt	db	0		;Output char count
iopptr	dw	iopbuf		;Output char ptr
iopfcb	db	0
	db	'RECORDER   '
initarea
	ds	24,version
closeflg
	db	0
iopbuf	ds	128,version
endinit
dosadd	dw	0	
dosptr	dw	0
ouruser	db	0
	ds	20,version
stack	dw	0
ostack	dw	0
savbuf	ds	147,version
;	ds	iops*128-$,version

	if $ gt iops*128
hoser hoser hoser to large
	endif
;
	end
ostack	dw	0
savbuf	ds	147,version
;	ds	iops*